﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using OAonline.Models;
using ServiceApplication.Service.WorkFlow;
using ServiceApplication.Service;
using System.Data;
using CommonLibrary.DataModel.Form;
using CommonLibrary.DataModel.WorkFlow;
using CommonLibrary.Common;
using System.Xml.Linq;
using Bukovics.Workflow.Hosting;
using CommonLibrary.DataModel.Basic;
using ServiceApplication.Service.Basic;
using System.Workflow.Activities;
using CommonLibrary.Wf.InterFace;
using System.Workflow.Runtime;
using System.IO;
using System.Xml;
using ServiceApplication.Dao.WorkFlow;
using System.Workflow.ComponentModel;
using System.Workflow.Runtime.Hosting;
using System.Transactions;

namespace OAonline.Controllers
{
    public class WorkFlowController : Controller
    {
        //
        // GET: /WorkFlow/
        WorkFlowService wfs = new WorkFlowService();
        BasicService bs = new BasicService();
        FormService fs = new FormService();
        SerializeDesigner designer = new SerializeDesigner();
        public ActionResult Index(UserModel user)
        {
            WorkFlowModel wfm = new WorkFlowModel
            {
                user_id = user.user.id.ToString(),
                dt_wf = wfs.QueryAllWf(),
                dt_wfworking = wfs.QueryTask(user.user.id.ToString(), "未处理"),
                dt_wfworked = wfs.QueryTask(user.user.id.ToString(), "已处理"),
            };
            return View(wfm);
        }


        //新建流程  
        public ActionResult WFNew(UserModel user)
        {
            DataTable dtType = wfs.QueryWftypeAll();
            DataTable dtForm = fs.QueryFreeForm();
            DataTable dtWftemplate = wfs.QueryWfTemplate();
            List<SelectListItem> list_wftype = new List<SelectListItem>();
            for (int i = 0; i < dtType.Rows.Count; i++)
            {
                list_wftype.Add(new SelectListItem
                {
                    Selected = false,
                    Text = dtType.Rows[i]["名称"].ToString(),
                    Value = dtType.Rows[i]["编码"].ToString(),
                });
            }
            List<SelectListItem> list_form = new List<SelectListItem>();
            for (int i = 0; i < dtForm.Rows.Count; i++)
            {
                list_form.Add(new SelectListItem
                {
                    Selected = false,
                    Text = dtForm.Rows[i]["名称"].ToString(),
                    Value = dtForm.Rows[i]["编码"].ToString(),
                });
            }
            List<SelectListItem> list_wftemplate = new List<SelectListItem>();
            for (int i = 0; i < dtWftemplate.Rows.Count; i++)
            {
                list_wftemplate.Add(new SelectListItem
                {
                    Selected = false,
                    Text = dtWftemplate.Rows[i]["名称"].ToString(),
                    Value = dtWftemplate.Rows[i]["编码"].ToString(),
                });
            }

            user.list_wftype = list_wftype;
            user.list_form = list_form;
            user.list_wftemplate = list_wftemplate;
            return View(user);
        }

        //发起流程  
        public ActionResult WFStart(string wf_id, string user_id)
        {
            if (string.IsNullOrEmpty(wf_id))
            {
                return Content("不存在wf_id");
            }
            if (string.IsNullOrEmpty(user_id))
            {
                return Content("不存在user_id");
            }

            WfEntity wfEntity = wfs.QueryWf(wf_id);
            FormEntity formEntity = fs.QueryFormEntity(wfEntity.form_id);

            if (formEntity == null)
            {
                return Content("不存在该表单");
            }

            XElement xml = XElement.Load(Server.MapPath("~/UploadFiles/Form/" + formEntity.location));
            WorkFlowModel wfm = new WorkFlowModel();
            ViewData["formdefi"] = designer.DeserializeXmlToWeb(xml);
            ViewData["form_id"] = formEntity.form_id.ToString();
            ViewData["wftemplate_id"] = wfEntity.wftemplate_id.ToString();
            ViewData["wf_id"] = wfEntity.wf_id.ToString();


            #region 获取下一步处理人类型
            WfClrxxInfo nextClr = wfs.getClrxxByFirstNext(
                (System.Web.HttpContext.Current.Application[MyWorkHelpr.WorkflowStaticTemplate] as Dictionary<int, StateMachineWorkflowInstance>), wfEntity.wftemplate_id);
            //初始化选择树
            ViewData["treedefi"] = ZTreeHelper.Serialize(bs.GetWebUserNodeList());

            if (nextClr != null)
            {
            
                if (nextClr.clzType == TaskClrType.由上一步处理人指定.ToString())
                {
          
                    ViewData["treevisible"] = "T";
                }
                else //特殊情况：ifelse活动的下一步处理人无法获取，所以不是 由上一步处理人指定 的情况，在createWorkflow 方法中clr传入null
                {
                    ViewData["treevisible"] = "F";
                }
            }
            #endregion

            return View(wfm);
        }

        //审批
        public ActionResult WFProcess(UserModel user)
        {
            string uniqueid = Request["uniqueid"];
            string task_id = Request["task_id"];
            string ptask_id = Request["ptask_id"];
            ViewData["task_id"] = task_id;
            ViewData["ptask_id"] = ptask_id;
            WfTaskEntity wfTaskEntity = TaskDao.Query(task_id);
            FormEntity formEntity = fs.QueryFormEntityByWfinsId(wfTaskEntity.uniqueid.ToString());

            ViewData["form_id"] = formEntity.form_id;
            List<WfInsvalueEntity> wfInsvalueEntitys = wfs.QueryInsvalue(ptask_id);

            //实例标识
            ViewData["uniqueid"] = uniqueid;
            //获取表单定义
            if (formEntity != null)
            {
                XElement xml = XElement.Load(Server.MapPath("~/UploadFiles/Form/" + formEntity.location));
                var sqlargs = wfs.getsqlargs(uniqueid);
                xml = designer.FillInsValueToXml(xml, wfInsvalueEntitys);
                ViewData["formdefi"] = designer.DeserializeXmlToWeb(xml,sqlargs);
            }
            //选择树定义
            ViewData["treedefi"] = ZTreeHelper.Serialize(bs.GetWebUserNodeList());
            //获取下一步操作选项
            var StepList = new List<SelectListItem>();
            DataTable dt = wfs.getNextStep(uniqueid, (System.Web.HttpContext.Current.Application[MyWorkHelpr.WorkflowRuntimeManager] as WorkflowRuntimeManager).WorkflowRuntime);
            foreach (DataRow item in dt.Rows)
            {
                StepList.Add(new SelectListItem() { Text = item["NTEXT"].ToString(), Value = item["NID"].ToString(), Selected = false });
            }
            ViewData["steplist"] = StepList;
            return View();
        }
        //任务明细
        public ActionResult WFTaskDetails(string uniqueId)
        {
            DataTable dt_task = wfs.QueryTaskByuniqueId(uniqueId);
            ViewData["dt_task"] = dt_task;
            return View();
        }

        #region 调用方法

        public ActionResult WFAdd(string user_id, string user_name, string new_name, string new_form, string new_type, string new_template, string new_bz)
        {
            if (string.IsNullOrEmpty(new_template)) return null;

            //判断表单和wf模板对应变量是否匹配
            WfTemplateEntity Template = wfs.QueryWfTemplate(int.Parse(new_template));
            FormEntity formEntity = fs.QueryFormEntity(int.Parse(new_form));
            if (null != formEntity.formfieldEntityList)//如果form表单中存在wf参数变量，则在rule中查询是否存在该变量名
            {
                List<string> args = new List<string>();
                foreach (var formfiledEntity in formEntity.formfieldEntityList)
                {
                    if (formfiledEntity.ifwfjudge != "")
                        args.Add(formfiledEntity.ifwfjudge);
                }
                for (int i = 0; i < args.Count; i++)
                {
                    if (!Template.wfrule.Contains(args[i]))
                    {
                        return Content(" 工作流模板中未存在输入变量 " + args[i] + " 请确认");
                    }
                }
            }
            WfEntity wfEntity = new WfEntity
            {
                wftemplate_id = int.Parse(new_template),
                form_id = int.Parse(new_form),
                wftype_id = int.Parse(new_type),
                name = new_name,
                pos = 0,
                usever = 1,
                createtime = DateTime.Now,
                lasttime = DateTime.Now,
                creater_id = int.Parse(user_id),
                creater_name = user_name,
                lastuser_id = -1,
                lastuser_name = string.Empty,
                users = string.Empty,
                depts = string.Empty,
                status = 0,
                descn = new_bz
            };
            wfs.AddWf(wfEntity);


            WorkflowInstance ins = null;
            WorkflowRuntimeManager workflowRuntimeManager = System.Web.HttpContext.Current.Application[MyWorkHelpr.WorkflowRuntimeManager] as WorkflowRuntimeManager;
            StateMachineWorkflowInstance stateMachineWorkflowInstance = null;
            TextReader t1 = new StringReader(Template.wfdefinition);
            TextReader t2 = new StringReader(Template.wfrule);
            XmlReader define = XmlReader.Create(t1);
            XmlReader rule = XmlReader.Create(t2);
            ins = workflowRuntimeManager.WorkflowRuntime.CreateWorkflow(define, rule, null);
            stateMachineWorkflowInstance = new
                 StateMachineWorkflowInstance(workflowRuntimeManager.WorkflowRuntime, ins.InstanceId);
            return RedirectToAction("SendMessage", "Message", new { url = "/WorkFlow/Index", message = "操作成功" });
        }

        public ActionResult WFStartManage(UserModel user)
        {
            string wf_name = Request["wf_name"];
            string form_id = Request["form_id"];
            string wftempid = Request["wftemplate_id"];
            string wf_id = Request["wf_id"];
            string sqlargs = Request["sqlargs"];
            int[] clrs = null;//只要处理方法不是 由上一步处理人指定，则该值一直保持null传入createWorkflow
            if (!string.IsNullOrEmpty(Request["selectarr"]))
            {
                string[] selectarr = Request["selectarr"].Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                clrs = Array.ConvertAll<string, int>(selectarr, delegate(string s) { return int.Parse(s); });
            }


            List<FormFieldEntity> ffeList = new FormService().QueryFormFieldEntitys(int.Parse(form_id), "text");//表单字段实体List
            List<WfInsvalueEntity> wivList = new List<WfInsvalueEntity>();//工作流实例值List
            Dictionary<string, string> dicsp = new Dictionary<string, string>();

            #region 获取页面上的工作流实例值(wivList)
            foreach (FormFieldEntity item in ffeList)
            {
                wivList.Add(new WfInsvalueEntity()
                {
                    task_id = 0,
                    fieldName = item.name,
                    fieldType = item.fieldtype,
                    fieldValue = Request.Form[item.name],//等待小马的答复.
                });
                if (!string.IsNullOrEmpty(item.ifwfjudge))
                {
                    dicsp.Add(item.ifwfjudge, Request.Form[item.name]);//将需要在wf中判断的字段存入dic中,传入启动的wf实例
                }
            }
            #endregion

            WorkflowRuntimeManager manager = (System.Web.HttpContext.Current.Application[MyWorkHelpr.WorkflowRuntimeManager] as WorkflowRuntimeManager);
            {
                manager.WorkflowRuntime.StartRuntime();
                manager.MessageEvent += delegate(
                    Object sender1, WorkflowLogEventArgs e1)
                {
                    Console.WriteLine(e1.Message);
                };

                WorkflowInstanceWrapper wfiw;
                

                UserEntity fqrEntity = bs.QueryUser(user.user.id);
                StartParameter sp = new StartParameter()
                    {
                        createrInfo = fqrEntity,
                        insValue = dicsp,
                        wfName = wf_name,//界面上获取,默认demo
                        nextYh = clrs
                    };
                wfiw = wfs.createWorkflow(
                    manager, int.Parse(wftempid), int.Parse(wf_id), sp, wivList,sqlargs,"",DateTime.Now,null);
            }
            return RedirectToAction("SendMessage", "Message", new { url = "/WorkFlow/Index", message = "操作成功" });
        }

        public ActionResult WFProcessManage(UserModel user)
        {
            string task_id = Request["task_id"];
            string ptask_id = Request["ptask_id"];

            string form_id = Request["form_id"];
            int[] clrs = null;//只要 处理方法不是 由上一步处理人指定，则该值一直保持null传入createWorkflow
            if (!string.IsNullOrEmpty(Request["selectarr"]))
            {
                string[] selectarr = Request["selectarr"].Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                clrs = Array.ConvertAll<string, int>(selectarr, delegate(string d) { return int.Parse(d); });
            }
            string s = Request["txtGUID"];
            string taskname = Request["steplist"];
            string task_des = Request["task_des"];

            Guid instanceId = new Guid(s);

            #region 数据获取: 表单值wivList
            List<FormFieldEntity> ffeList = new FormService().QueryFormFieldEntitys(int.Parse(form_id), "text");
            List<WfInsvalueEntity> wivList = new List<WfInsvalueEntity>();
            //Dictionary<string,object> 
            foreach (FormFieldEntity item in ffeList)
            {
                wivList.Add(new WfInsvalueEntity()
                {
                    task_id = int.Parse(task_id),
                    fieldName = item.name,
                    fieldType = item.fieldtype,
                    fieldValue = Request.Form[item.name]
                });
            }
            #endregion
            WorkflowRuntimeManager manager = (System.Web.HttpContext.Current.Application[MyWorkHelpr.WorkflowRuntimeManager] as WorkflowRuntimeManager);
            {
                wfs.ProcessWorkflow(manager, instanceId, user.user,task_id, ptask_id,taskname, task_des, form_id, wivList, clrs,
                    (System.Web.HttpContext.Current.Application[MyWorkHelpr.WorkflowStaticTemplate] as Dictionary<int, StateMachineWorkflowInstance>));
            }

            return RedirectToAction("SendMessage", "Message", new { url = "/WorkFlow/Index", message = "操作成功" });
        }

        //当处理界面选择不同的处理方式时，根据处理名称查找下一步的处理方式
        [HttpPost]
        public JsonResult InityTree(string taskname, string guid)
        {
            JsonResult jr = new JsonResult();
            //如果为空，则说明是选择了默认的那条，不用操作生成树
            //备注：设置默认条目是为了让客户初次进行选择操作来触发当前方法，
            //           初始化的时候进行是否生成树判断比较麻烦，所以采取了让客户进行选择操作的方法
            if (string.IsNullOrEmpty(taskname))
            {
                jr.Data = "[]";
                return jr;
            }
            Guid instanceId = new Guid(guid);
            StateMachineWorkflowInstance stateInstance = new StateMachineWorkflowInstance(
              (System.Web.HttpContext.Current.Application[MyWorkHelpr.WorkflowRuntimeManager] as WorkflowRuntimeManager).WorkflowRuntime, instanceId);
            EventDrivenActivity edact = (EventDrivenActivity)stateInstance.CurrentState.Activities[taskname];

            WfEntity wfEntity = wfs.QueryWfByuniqueid(guid);
            WfClrxxInfo clrxx = wfs.getNextClrxxByTaskName(
                (System.Web.HttpContext.Current.Application[MyWorkHelpr.WorkflowStaticTemplate] as Dictionary<int, StateMachineWorkflowInstance>),
                wfEntity.wftemplate_id, edact.Parent.Name, edact.Description);

            if (clrxx == null)
            {
                jr.Data = "[]";
            }
            else
            {
                if (clrxx.clzType == TaskClrType.由上一步处理人指定.ToString())
                {
                    jr.Data = ZTreeHelper.Serialize(bs.GetWebUserNodeList());
                }
                else
                {
                    jr.Data = "[]";
                }
            }
            return jr;
        }

        #endregion
    }
}